package com.melon.entity;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;

/**
 * 服务详情
 *
 * @author zhangzhuo
 * @version 1.0
 * @date 2024-10-15
 */
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@Slf4j
public class PowerAssistServiceInfoVM {

    private String serviceName;

    private ServiceConfigVM serviceConfig;

    private FailoverConfigVM failoverConfig;

    private ExpandContractConfigVM expandContractConfig;

    private List<ContainerInfoVM> containerList;

    @Data
    public static class ServiceConfigVM{

        private String imageName;

        private String serviceType;

        private String serviceAppType;

        private ServiceDeploymentImageResourceConfigVM resource;

        private String policy;

        private List<StaticPolicyNodeVM> staticPolicyConfig;

        private DynamicPolicyConfigVM dynamicPolicyConfig;

    }

    @Data
    public static class NodeVM{
        private Long id;

        private String name;

        private String address;
    }

    @Data
    @EqualsAndHashCode(callSuper = true)
    public static class StaticPolicyNodeVM extends NodeVM{
        private Integer factor;
    }

    @Data
    public static class DynamicPolicyConfigVM{

        private List<NodeVM> nodes;

        private Integer factor;
    }

    @Data
    public static class FailoverConfigVM{
        private Boolean failoverEnabled;

        private List<NodeVM> failoverNodes;
    }

    @Data
    public static class ExpandContractConfigVM{

        private Boolean expandContractEnabled;


        private String strategy;


        private List<NodeVM> expandNodes;


        private Boolean studyEnable;


        private String frequency;

        /**
         * 静态开始时间
         */

        private Date staticStartTime;

        /**
         * 静态结束时间
         */

        private Date staticEndTime;

        /**
         * 循环
         */

        private Integer cycle;

        /**
         * 循环开始时间
         */

        private Date cycleTime;

        /**
         * 循环持续时间：分钟
         */

        private Integer cycleDuration;

        /**
         * 动态最大节点数
         */

        private Integer dynamicMaxCount;

        /**
         * 动态指标类型
         */

        private String dynamicIndexType;

        /**
         * 动态阈值
         */

        private Double dynamicThreshold;
    }

    @Data

    public static class ContainerInfoVM{

        private String containerId;

        private String name;

        private String status;

        private String appId;

        private NodeVM deployNode;

        private Boolean owner;

        /**
         * 容器部署来源：0 创建来的容器，1 扩容来的容器，2 手动迁移来的容器，3 故障迁移来的容器，4 算力协助来的容器
         */
        private Integer deploySource;

        private ContainerMetricVM metric;
    }

    @Data
    public static class ContainerMetricVM {

        private Long memoryLimit;

        private Long memoryMaxUsage;

        private Long memoryUsage;

        private Long memoryTotal;

        private JsonNode cpuUsage;

        private String status;

        @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
        private Date created;

        @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
        private Date started;

        @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
        private Date time;

        private Integer deploySource;

        public Date getCreated() {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
            try {
                if (this.created != null) {
                    return dateFormat.parse(dateFormat.format(this.created));
                }
                return null;
            } catch (ParseException e) {
                return null;
            }
        }

        public Date getStarted() {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
            try {
                if (this.started != null) {
                    try {
                        if(DateUtils.isSameDay(this.started, Date.from(LocalDate.of(1970, 1, 1).atStartOfDay(ZoneId.systemDefault()).toInstant()))) {
                            return null;
                        }
                    } catch (Exception exception) {
                        log.error("【get container metric info's started time error】",exception);
                    }

                    return dateFormat.parse(dateFormat.format(this.started));
                }
                return null;
            } catch (ParseException e) {
                return null;
            }
        }

        public Date getTime() {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
            try {
                if (this.time != null) {
                    return dateFormat.parse(dateFormat.format(this.time));
                }
                return null;
            } catch (ParseException e) {
                return null;
            }
        }

        /**
         * 上线时间
         */
        private Long uptime;

        /**
         * 容器部署次数
         */
        private int deployNum;

        /**
         * 重启次数
         */
        private int restartCnt;
    }

}
